package BACK;

import javax.swing.*;
import javax.swing.Timer;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.time.*;
import java.time.format.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.*;
import java.util.stream.Collectors;

/**
 * 基于原生Thread实现的多线程抽卡模拟器
 */
public class GachaSimulator extends JFrame {
    // 线程安全状态管理
    private final AtomicInteger recruitPoints = new AtomicInteger(0); // 原子操作计数器
    private final int MAX_RECRUIT = 232;
    private final List<Character> history = Collections.synchronizedList(new LinkedList<>()); // 同步历史记录

    // 线程控制
    private final ReentrantLock lock = new ReentrantLock();          // 线程同步锁
    private final Condition threadsCompleted = lock.newCondition(); // 线程完成条件
    private int activeThreads = 0;                                   // 活跃线程计数器

    // 卡池数据
    private final List<Character> currentPool = new ArrayList<>();

    // UI组件
    private JLabel timeLabel = new JLabel("4:35");
    private JLabel recruitLabel = new JLabel("0/" + MAX_RECRUIT);
    private javax.swing.Timer clockTimer;

    public GachaSimulator() {
        initPool();
        initUI();
        startClock();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
    }

    /**
     * 初始化卡池数据
     */
    private void initPool() {
        // 当期UP角色（优 泳装）
        currentPool.add(new Character("优", 3, true, "泳装", "限定"));

        // 添加三星角色（使用冒号分隔变体信息）
        addThreeStarCharacters(
                "大野月咏", "戒野美咘", "槌永日和", "秤亚津子", "锭前纱织",
                "野宫:泳装", "若藻:泳装", "杏山和纱", "歌原:应援团",
                "生盐诺亚", "春原心奈", "明星日鞠", "各务千寻", "水羽三森",
                "古关忧", "若叶日向", "池仓真里奈", "砂狼白子:骑行",
                "小鸟游星野", "天童爱丽丝", "空崎日奈", "银镜伊织",
                "黑馆晴奈", "陆八魔爱露", "白子:泳装", "宫子:泳装",
                "咲:泳装", "三森:泳装", "琴里:应援团", "日向:泳装"
        );

        // 二星角色（无变体）
        addTwoStarCharacters(
                "鳄渊明里", "赤司纯子", "浅黄睦月", "鬼方佳代子",
                "爱清风香", "早濑优香", "月雪宫子", "浦和花子",
                "中务桐乃", "宇泽玲纱", "桑上果穗", "朱城瑶海"
        );

        // 一星角色（无变体）
        addOneStarCharacters(
                "火宫千夏", "伊草春香", "牛牧朱莉", "音濑小玉",
                "一之濑明日奈", "丰见琴里", "朝比奈菲娜",
                "守月铃美", "圆堂志美子", "鹭见芹娜", "伊原木好美"
        );
    }

    private void addThreeStarCharacters(String... entries) {
        Arrays.stream(entries).forEach(e -> {
            String[] parts = e.split(":");
            currentPool.add(new Character(
                    parts[0], 3, false,
                    parts.length > 1 ? parts[1] : "",
                    parts.length > 2 ? parts[2] : ""
            ));
        });
    }

    private void addTwoStarCharacters(String... names) {
        Arrays.stream(names).forEach(n ->
                currentPool.add(new Character(n, 2, false, "", ""))
        );
    }

    private void addOneStarCharacters(String... names) {
        Arrays.stream(names).forEach(n ->
                currentPool.add(new Character(n, 1, false, "", ""))
        );
    }

    /**
     * 初始化用户界面
     */
    private void initUI() {
        setTitle("蔚蓝档案抽卡模拟器");
        setSize(800, 600);
        setLayout(new BorderLayout());

        // 顶部状态栏
        add(createStatusBar(), BorderLayout.NORTH);

        // 底部操作按钮
        JPanel buttonPanel = new JPanel(new GridLayout(1, 4, 10, 0));
        String[] buttons = {"单次招募", "十连招募", "兑换UP角色", "招募记录"};
        for (String text : buttons) {
            JButton btn = new JButton(text);
            btn.addActionListener(this::handleAction);
            buttonPanel.add(btn);
        }
        add(buttonPanel, BorderLayout.SOUTH);
    }

    private JPanel createStatusBar() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10));

        // 左侧状态
        JPanel left = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 0));
        left.add(new JLabel("5G"));
        left.add(new JLabel("电量 50%"));

        // 右侧状态
        JPanel right = new JPanel(new FlowLayout(FlowLayout.RIGHT, 15, 0));
        right.add(timeLabel);
        right.add(new JLabel("货币: 254,877,048"));
        right.add(new JLabel("钻石: 69,615"));
        right.add(new JLabel("招募进度: "));
        right.add(recruitLabel);

        panel.add(left, BorderLayout.WEST);
        panel.add(right, BorderLayout.EAST);
        return panel;
    }

    /**
     * 处理按钮事件
     */
    private void handleAction(ActionEvent e) {
        String cmd = ((JButton)e.getSource()).getText();
        switch (cmd) {
            case "单次招募": performGacha(1); break;
            case "十连招募": performGacha(10); break;
            case "兑换UP角色": exchangeUp(); break;
            case "招募记录": showHistory(); break;
        }
    }

    /**
     * 多线程抽卡核心方法
     */
    private void performGacha(int times) {
        // 创建结果容器（线程安全）
        List<Character> results = Collections.synchronizedList(new ArrayList<>(times));

        lock.lock();
        try {
            activeThreads = times;
            // 启动指定数量的抽卡线程
            for (int i = 0; i < times; i++) {
                new GachaThread(results).start();
            }

            // 等待所有线程完成
            while (activeThreads > 0) {
                threadsCompleted.await();
            }
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }

        // 在EDT线程更新UI
        EventQueue.invokeLater(() -> {
            showResults(results);
            updateStatus();
        });
    }

    /**
     * 自定义抽卡线程
     */
    private class GachaThread extends Thread {
        private final List<Character> results;

        public GachaThread(List<Character> results) {
            this.results = results;
        }

        @Override
        public void run() {
            try {
                // 执行抽卡逻辑
                Character c = gachaPull();

                // 原子更新招募点数
                recruitPoints.updateAndGet(v -> Math.min(v + 1, MAX_RECRUIT));

                // 同步添加历史记录
                synchronized(history) {
                    history.add(0, c); // 最新记录在前
                }

                // 添加结果到集合
                synchronized(results) {
                    results.add(c);
                }
            } finally {
                lock.lock();
                try {
                    activeThreads--;
                    threadsCompleted.signalAll(); // 通知主线程
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    /**
     * 单次抽卡概率计算
     */
    private Character gachaPull() {
        double rand = ThreadLocalRandom.current().nextDouble(100);
        if (rand < 0.7) return getUpCharacter();
        else if (rand < 3.0) return getRandom(3, false);
        else if (rand < 21.5) return getRandom(2, false);
        else return getRandom(1, false);
    }

    private Character getUpCharacter() {
        return currentPool.stream()
                .filter(c -> c.isUp)
                .findFirst()
                .orElseThrow();
    }

    private Character getRandom(int star, boolean includeUp) {
        List<Character> candidates = currentPool.stream()
                .filter(c -> c.star == star && (includeUp || !c.isUp))
                .collect(Collectors.toList());
        return candidates.get(ThreadLocalRandom.current().nextInt(candidates.size()));
    }

    /**
     * 显示抽卡结果
     */
    private void showResults(List<Character> results) {
        JDialog dialog = new JDialog(this, "抽卡结果", true);
        JPanel grid = new JPanel(new GridLayout(0, 5, 5, 5));

        results.forEach(c -> {
            JPanel card = new JPanel(new BorderLayout());
            card.setBorder(BorderFactory.createTitledBorder(c.star + "星"));
            card.add(new JLabel(c.toString(), SwingConstants.CENTER));
            grid.add(card);
        });

        dialog.add(new JScrollPane(grid));
        dialog.setSize(600, 400);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }

    /**
     * 兑换UP角色功能
     */
    private void exchangeUp() {
        if (recruitPoints.get() >= 200) {
            recruitPoints.addAndGet(-200);
            Character up = getUpCharacter();
            synchronized(history) {
                history.add(0, up);
            }
            JOptionPane.showMessageDialog(this, "成功兑换UP角色：" + up);
            updateStatus();
        } else {
            JOptionPane.showMessageDialog(this,
                    "点数不足！当前点数：" + recruitPoints.get(),
                    "兑换失败",
                    JOptionPane.WARNING_MESSAGE);
        }
    }

    /**
     * 显示招募记录
     */
    private void showHistory() {
        JDialog dialog = new JDialog(this, "招募记录", true);
        String[] columns = {"时间", "角色", "星级", "标签"};
        DefaultTableModel model = new DefaultTableModel(columns, 0) {
            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };

        synchronized(history) {
            history.forEach(c -> model.addRow(new Object[]{
                    LocalDateTime.now().format(DateTimeFormatter.ofPattern("MM-dd HH:mm")),
                    c.name,
                    "★".repeat(c.star),
                    c.variant.isEmpty() ? c.special : c.variant
            }));
        }

        JTable table = new JTable(model);
        table.setAutoCreateRowSorter(true);
        dialog.add(new JScrollPane(table));
        dialog.setSize(800, 600);
        dialog.setLocationRelativeTo(this);
        dialog.setVisible(true);
    }

    /**
     * 更新界面状态
     */
    private void updateStatus() {
        recruitLabel.setText(recruitPoints.get() + "/" + MAX_RECRUIT);
    }

    /**
     * 实时时钟
     */
    private void startClock() {
        clockTimer = new Timer(1000, e -> {
            timeLabel.setText(LocalTime.now()
                    .format(DateTimeFormatter.ofPattern("HH:mm")));
        });
        clockTimer.start();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            GachaSimulator simulator = new GachaSimulator();
            simulator.setVisible(true);
        });
    }
}

/**
 * 角色实体类
 */
class Character {
    String name;
    int star;
    boolean isUp;
    String variant;
    String special;

    public Character(String name, int star, boolean isUp, String variant, String special) {
        this.name = name;
        this.star = star;
        this.isUp = isUp;
        this.variant = variant;
        this.special = special;
    }

    @Override
    public String toString() {
        return name + (variant.isEmpty() ? "" : "("+variant+")") +
                (special.isEmpty() ? "" : "【"+special+"】") +
                " ★".repeat(star);
    }
}